package com.shelpe.services.simbasync.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.shelpe.services.simbasync.dao.ProductsMapper;
import com.shelpe.services.simbasync.exception.ApiException;
import com.shelpe.services.simbasync.model.Products;
import com.shelpe.services.simbasync.model.ProductsExample;
import com.shelpe.services.simbasync.model.Users;
import com.shelpe.services.simbasync.service.ProductsService;
import com.shelpe.services.simbasync.service.simbaproxy.ProductsProxy;


@Service
public class ProductsServiceImpl implements ProductsService {

	private static final Logger logger = LoggerFactory.getLogger(ProductsServiceImpl.class);
	
	@Autowired
	private ProductsMapper mapper;
	
	@Autowired
	private ProductsProxy proxy;
	
	@Value("${simbasync.mainInnerUserId}")
	private String mainInnerUserId;
	
    private final List<Long> innerUserIdList = new ArrayList<Long>();
	
	@Override
	public int addItem(Products product) {
		// TODO Auto-generated method stub
		return mapper.insert(product);
	}

	@Override
	public int addItems(List<Products> products) {
		// TODO Auto-generated method stub
		int num = 0;
		for(Products item : products){
			mapper.insert(item);
		}
		return num;
	}
	
	public int insertItemBatch(List<Products> products){
		int num = 0;
		int pageSize = 15000;
		
		if(products != null && products.size() > 0){
			int fromIndex = 0;
			int endIndex = 0;
			do{
				
				endIndex += pageSize; 
				if(endIndex > products.size()){
					endIndex = products.size();
				}
				num += mapper.insertBatch(products.subList(fromIndex, endIndex));	
				fromIndex += pageSize; 
			
			}while(fromIndex < products.size());
		}
		
		return num;
	}
	
	@Override
	public int deleteItems(List<Products> products){
		int num = 0;
		for(Products p : products){
			num += mapper.deleteByPrimaryKey(p.getNumIid());
		}
		return num;
	}
	
	@Override
	public int updateItems(List<Products> products){
		int num = 0;
		for(Products p : products){
			num += mapper.updateByPrimaryKey(p);
		}
		return num;
	}
	
	@Override
	public int deleteItemById(long numIid){
		return mapper.deleteByPrimaryKey(numIid);
	}

	@Override
	public Products getItemById(long numIid) {
		// TODO Auto-generated method stub
		return mapper.selectByPrimaryKey(numIid);
	}
	
	@Override
	public List<Products> getItemsByUserId(long userId){
		ProductsExample ex = new ProductsExample();
		ex.createCriteria().andUserIdEqualTo(userId);
		
		return mapper.selectByExample(ex);
	}
	
	@Override
	public List<Products> parseJsonToProducts(String response){
		
		List<Products> res = new ArrayList<Products>();
		
		if(response != null && response.contains("simba_adgroup_onlineitemsvon_get_response")){
			JSONObject object = JSON.parseObject(response);
			JSONObject objRes = object==null? null : object.getJSONObject("simba_adgroup_onlineitemsvon_get_response");
			JSONObject objItems = objRes==null? null : objRes.getJSONObject("page_item");
			JSONObject objList = objItems==null? null : objItems.getJSONObject("item_list");
			JSONArray jsonList = objList==null? null : objList.getJSONArray("subway_item");
			int size = jsonList == null? 0 : jsonList.size();
		    String subStr = "_sum.jpg";
		    int subStrLen = subStr.length();
			String lastDateStr = "1970-01-01 00:00:00";
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			
			for(int i = 0; i< size; i++){
				Products item = new Products();
				JSONObject obj = jsonList.getJSONObject(i);
				
				item.setNumIid(obj.getLong("num_id"));
				item.setPrice(BigDecimal.valueOf(Double.parseDouble(obj.getString("price"))));
				item.setTitle(obj.getString("title"));
				
				String picUrl = obj.getString("img_url");
				int urlLen = picUrl.length();
				
				if(picUrl.endsWith(subStr)){
					picUrl = picUrl.substring(0, urlLen - subStrLen);
				}
   
				item.setPicUrl(picUrl); 
				JSONObject objExtra = obj.getJSONObject("extra_attributes");
				
				item.setQuantity(objExtra.getInteger("quantity"));
				item.setSalesCount(objExtra.getInteger("sales_count"));
				Date publish_time = objExtra.getDate("publish_time");
				
				if(publish_time == null){//api中会缺失该字段

					try {
						publish_time = sdf.parse(lastDateStr);
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				item.setPublishTime(publish_time);
				
				Date defaultDate = new Date();
				try {
					defaultDate = sdf.parse(lastDateStr);
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				item.setCid(0);
				item.setDelistTime(defaultDate);
				item.setItemImgs("");
				item.setListTime(defaultDate);
				item.setModified(defaultDate);
				item.setNum(0);
				item.setPropertyAlias("");
				item.setProps("");
				item.setPropsName("");
				item.setStuffStatus("");
				item.setType("");
				item.setDetailUrl("");
				item.setCatName("");
				
				res.add(item);
			}
		}else{
			logger.warn("can not get any info from proxy, maybe something is wrong, api is parseJsonToProducts, response: {}", response);
			throw new ApiException();
		}
		
		return res;
	}
	
	@Override
	public void updateProductsData(Users user, List<Products> items){
	
		Long userId = user.getUserId();
		Date updateTime = new Date();
		String fields = "cid,delist_time,num, pic_url,list_time,num_iid,props_name,props,stuff_status,modified,property_alias,item_img";
		for(Products item : items){
			item.setUpdated(updateTime);
			item.setUserId(userId);
		
			if(isInnerUser(user)){
				continue;
			}
			
			String response = null;
			try{
				response = proxy.getItemsDetailInfo(userId, item.getNumIid(), fields);
			}catch(Exception e){
				e.printStackTrace();
			}
			
			if(response != null && response.contains("item_seller_get_response")){
				
				JSONObject object = JSON.parseObject(response);
				JSONObject objRes = object==null? null : object.getJSONObject("item_seller_get_response");
				JSONObject objItem = objRes==null? null : objRes.getJSONObject("item");
				
				item.setCid(objItem.getInteger("cid"));
				item.setDelistTime(objItem.getDate("delist_time"));
				
				JSONObject objItemImgs = objItem == null? null : objItem.getJSONObject("item_imgs");
				JSONArray imgs = objItemImgs == null ? null : objItemImgs.getJSONArray("item_img");
				JSONArray itemImgs = new JSONArray();
				
				if(imgs != null){
					for(int i = 1; i < imgs.size(); i++){//第一张不要
						itemImgs.add(imgs.getJSONObject(i).getString("url"));
					}
				}
				
				if(itemImgs != null && itemImgs.size() > 0){
					item.setItemImgs(itemImgs.toJSONString());
				}
			
				item.setListTime(objItem.getDate("list_time"));
				item.setModified(objItem.getDate("modified"));
				item.setNum(objItem.getInteger("num"));
				item.setPropertyAlias(objItem.getString("property_alias"));
				item.setProps(objItem.getString("props"));
				item.setPropsName(objItem.getString("props_name"));
				item.setStuffStatus(objItem.getString("stuff_status"));
			//	item.setType("");
			//	item.setDetailUrl("");
			//	item.setCatName("");
			}
		}
	}
	
	@Override
	public Map<String, List<Products> > splitProducts(List<Products> newList, List<Products> oldList) {
		
		Map<String, List<Products> > ret = new HashMap<String, List<Products> >();
		List<Products> updated = new ArrayList<Products>();
		List<Products> deleted = new ArrayList<Products>();
		List<Products> added = new ArrayList<Products>();
		Set<Long> newAdIds = new HashSet<Long>();
		int oldSize = oldList == null? 0 : oldList.size();
		int i = 0;
		
		for(Products newItem : newList){
			
			for(i = 0; i < oldSize; i++){
				Products oldItem = oldList.get(i);
				if(newItem.getNumIid().equals(oldItem.getNumIid())){
					//比较其他字段是否相同
					if(!isEqualProducts(newItem, oldItem)){
						if(oldItem.getType() != null){
							newItem.setType(oldItem.getType());
						}
						if(oldItem.getDetailUrl() != null){
							newItem.setDetailUrl(oldItem.getDetailUrl());
						}
						if(oldItem.getCatName() != null){
							newItem.setCatName(oldItem.getCatName());
						}

						updated.add(newItem);
					}
					break;
				}
			}
			if(i == oldSize){
				added.add(newItem);
			}
			newAdIds.add(newItem.getNumIid());
		}
		
		for(Products oldItem : oldList){
			if(!newAdIds.contains(oldItem.getNumIid())){
				deleted.add(oldItem);
			}
		}
		ret.put("delete", deleted);	
		ret.put("update", updated);	
		ret.put("add", added);	
				
		return ret;
	}
	
	private boolean isEqualProducts(Products newAd, Products oldAd){
		
		if(newAd.getModified().getTime() == oldAd.getModified().getTime() &&
				newAd.getPrice().compareTo(oldAd.getPrice()) == 0 && 
				newAd.getQuantity().equals(oldAd.getQuantity()) &&
				newAd.getTitle().equals(oldAd.getTitle()) &&
				newAd.getSalesCount().equals(oldAd.getSalesCount()) &&
				newAd.getItemImgs().equals(oldAd.getItemImgs()) &&
				newAd.getCid().equals(oldAd.getCid()) &&
				newAd.getPicUrl().equals(oldAd.getPicUrl()) ){
			return true;
		}
		
		return false;
	}
	
	private boolean isInnerUser(Users user){
		
		if(innerUserIdList.size() == 0){

			if(mainInnerUserId != null){
				String[] innerUserId = mainInnerUserId.split(",");

				if(innerUserId != null && innerUserId.length > 0){
					for(int i = 0; i < innerUserId.length; i++){
						innerUserIdList.add(Long.valueOf(innerUserId[i]));
					}
				}
			}
		}
		
		Long userId = user.getUserId();
		Long authorizedTo = user.getAuthorizedTo();
		
		return ( userId < 0 && innerUserIdList.contains(authorizedTo) );
	}
	
	
}